package com.weme.live.viewmode

import android.util.Log
import android.widget.EditText
import androidx.lifecycle.MutableLiveData
import com.weme.chat.bean.CallMessage
import com.weme.common.arouter.LiveRoomBean
import com.weme.common.base.BaseViewModel
import com.weme.common.network.NetWorkUrl
import com.weme.common.util.AgoraClient.sendImCallMsg
import com.weme.common.util.AppMkHelper
import com.weme.common.util.AppMkHelper.CallConfigBean
import com.weme.common.util.DeviceId.getDeviceLanguage
import com.weme.common.util.UserMKHelper
import com.weme.common.util.gson
import com.weme.live.activity.liveview.Message
import dev.kratos.api.cms_server.v1.CallConfig
import dev.kratos.api.cms_server.v1.CallConfigRequest
import dev.kratos.api.im_server.v1.*
import dev.kratos.api.user_server.v1.*
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import java.util.concurrent.TimeUnit

class LiveViewMode : BaseViewModel() {
    var anchorId = 0L
    var anchorUser: Users? = null

    var isFictitious = false //营销视频
    var isMatch = false
    var isIncoming = false // 是否是呼入
    var channelName = ""
    var liveRoomBean: LiveRoomBean? = null //传进来的参数
    var edTextView: EditText? = null

    var account: Accounts? = null


    var liveDuration = 0L // 直播时长


    //view 相关
    var gestureGuideFinishedLiveData = MutableLiveData<Any>()
    var navigateToReviewPageLiveData = MutableLiveData<Any>() //离开房间

    // var textInputChangeLiveData = MutableLiveData<Boolean>()
    var followLiveData = MutableLiveData<Boolean>()
    var sendMsgLiveData = MutableLiveData<Any>() //发消息
    var startTimingLiveData = MutableLiveData<Long>() //匹配计时
    var updateTimingLiveData = MutableLiveData<Long>() //更新计时
    var finalCountdownLiveData = MutableLiveData<Long>() //金币不够扣下一分钟
    var showKeyboardLiveData = MutableLiveData<Boolean>() //是否显示软键盘
    var updateUserInfoLiveData = MutableLiveData<Users>() //刷新主播信息
    var updateAccountLiveData = MutableLiveData<Accounts>() //更新账户信息
    var screenClearLiveData = MutableLiveData<Boolean>() //是否清屏


    //视频相关
    var switchCamera = MutableLiveData<Any>()


    //聊天室相关
    var sendMsgContentLiveData = MutableLiveData<Message>()
    var addMsgContentLiveData = MutableLiveData<Message>()//添加消息 到聊天框  对方发的
    var setInputMsgLiveData = MutableLiveData<String>() //输入框内容变化
    var translateMsgContentLiveData = MutableLiveData<String>()//翻译

    val compositeDisposable = CompositeDisposable()

    var callConfig: CallConfig? = null
    var isCallEndingNotifier = false //是否即将结束


    fun retrieveCallConfig(): CallConfig {
        if (callConfig == null || callConfig!!.normalIncomeTime == 0) { // 从 MMKV 中获取数据
            val callConfigBean = AppMkHelper.decodeString(CallConfigBean)
            callConfig = gson.fromJson(callConfigBean, CallConfig::class.java)
        }
        return callConfig!!
    }

    /**
     * 检查账户余额是否足够进行下一分钟的通话
     * @param callConfig 通话配置信息
     * @return 如果余额足够，返回 true；否则返回 false
     */
    fun checkCoinSufficientForNextMinute(callConfig: CallConfig): Boolean {
        val coins = account?.coins ?: 0  // 获取账户中的余额，若为空则默认为0
        val normalCall = callConfig.normalCall  // 获取正常通话所需的费用
        Log.e("live", "coins=$coins normalCall=$normalCall")
        return normalCall >= coins  // 判断余额是否足够进行下一分钟的通话
    }

    /**
     * 播放营销视频第一帧回调，开始倒计时
     */
    fun startTimer() {
        // 如果已有计时任务，直接返回
        if (compositeDisposable.size() > 0) {
            return
        }

        val callConfig = retrieveCallConfig()  // 获取通话配置
        if (isMatch) {
            startTimingLiveData.postValue(callConfig.matchCallTime.toLong())  // 如果是匹配模式，更新开始计时的 LiveData
        }

        // 创建一个 Observable 用于计时，每秒发出一次事件
        val timerObservable = Observable.interval(1, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe { elapsedTime ->
                Log.e("live",elapsedTime.toString())
                handleElapsedTime(elapsedTime, callConfig)  // 处理每秒发出的事件
            }

        // 将 Disposable 添加到 CompositeDisposable，以便在 Activity 销毁时进行处理
        compositeDisposable.add(timerObservable)
    }

    /**
     * 处理每秒钟的计时事件
     * @param elapsedTime 已经过的时间（以秒为单位）
     * @param callConfig 通话配置信息
     */
    private fun handleElapsedTime(elapsedTime: Long, callConfig: CallConfig) {
        if (elapsedTime % 10 == 0L) {  // 每10秒发送一次心跳请求
            sendImNetworkRequest(HeartVideoRequest.newBuilder().setChannelName(channelName).build().toByteArray(), NetWorkUrl.HeartVideo)
        }

        liveDuration = elapsedTime  // 记录通话时长

        if (isMatch) {
            handleMatchElapsedTime(elapsedTime, callConfig)  // 处理匹配模式下的计时事件
        } else {
            handleNormalElapsedTime(elapsedTime, callConfig)  // 处理正常模式下的计时事件
        }
    }

    /**
     * 处理匹配模式下的计时事件
     * @param elapsedTime 已经过的时间（以秒为单位）
     * @param callConfig 通话配置信息
     */
    private fun handleMatchElapsedTime(elapsedTime: Long, callConfig: CallConfig) {
        if (elapsedTime >= callConfig.matchCallTime.toLong()) {
            navigateToReviewPageLiveData.postValue("")  // 如果经过的时间达到匹配通话时间，导航到回顾页面
        }
    }

    /**
     * 处理正常模式下的计时事件
     * @param elapsedTime 已经过的时间（以秒为单位）
     * @param callConfig 通话配置信息
     */
    private fun handleNormalElapsedTime(elapsedTime: Long, callConfig: CallConfig) {
        if (callConfig.normalCall != 0) {  // 如果正常通话时间不为0
            if (isCallEndingNotifier && (elapsedTime % 60) == 0L&&elapsedTime>0) {  // 如果已经显示最后倒计时，并且倒计时结束
                navigateToReviewPageLiveData.postValue("")  // 退出房间
            } else if (!isCallEndingNotifier) {  // 如果未显示即将结束
                updateTimingLiveData.postValue(elapsedTime)  // 更新计时 LiveData
            }
        } else {
            // 如果正常通话时间为0，请求通话配置
            sendCmsNetworkRequest(CallConfigRequest.newBuilder().setAppId(APPID).build().toByteArray(), NetWorkUrl.CallConfig)
        }
    }


    //充值成功
    fun rechargedSuccessfully() {
        if (!isMatch) {
            isCallEndingNotifier = false
        }


    }
    fun setTranslate(msg:String){
        sendImNetworkRequest(TranslateRequest.newBuilder().addContent(msg).setTargetLang(getDeviceLanguage()).build().toByteArray(),NetWorkUrl.LiveTranslate)
    }
    fun getLiveUserInfo(req: GetUserInfoRequest) {
        val reqByte = req.toByteArray()
        sendNetworkRequest(reqByte, NetWorkUrl.LiveGetUserInfo)
    }

    fun setFollowApi(req: FollowRequest) {
        sendNetworkRequest(req.toByteArray(), NetWorkUrl.LiveFollow)
    }


    fun sendGift(req: SendGiftRequest) { //发送礼物
        sendNetworkRequest(req.toByteArray(), NetWorkUrl.SendGiftLive)
    }

    fun getChannelInfo() {
        sendImNetworkRequest(GetChannelInfoRequest.newBuilder().build().toByteArray(), NetWorkUrl.GetChannelInfo)
    }

    fun getRtcToken() { //获取rtcTOken  现在没在用这个 虽然写了 还有问题 如果进房间没拿到rtctoken  从这里获取
        sendImNetworkRequest(GetRtcTokenRequest.newBuilder().build().toByteArray(), NetWorkUrl.GetRtcToken)
    }


    fun setFirstFrame() { //远端收到第一针 发消息给服务端
        sendImNetworkRequest(FirstFrameRequest.newBuilder().setChannelName(channelName).build().toByteArray(), NetWorkUrl.FirstFrame)
    }

    fun putHangUp() { //退出房间
        //只有发起方发送消息
       liveRoomBean?.let {
           liveRoomBean = null
           isSednMsg()
           sendImNetworkRequest(ReportCallDurationRequest.newBuilder().setChannelName(channelName).setDuration(liveDuration.toInt()).build().toByteArray(), NetWorkUrl.ReportCallDuration)
           if (isFictitious) {
                sendImNetworkRequest(HangUpVideoRequest.newBuilder().setToUid(anchorId).build().toByteArray(), NetWorkUrl.HangUpVideo)
            } else {
                sendImNetworkRequest(HangUpVideoRequest.newBuilder().setToUid(anchorId).setChannelName(it.channelName).setChatRoomId(it.chatRoomId).build().toByteArray(), NetWorkUrl.HangUpVideo)
            }

        }
    }

    fun isSednMsg() {
        if (!isIncoming) {
            val finalDuration = if (isMatch && liveDuration > 30) 30L else liveDuration
            sendImCallMsg(anchorId.toString(), CallMessage(isMatch, finalDuration))
        }
    }

    //发送聊天消息

}